﻿using System;
using System.Runtime.InteropServices;

public  class GlobalMembersGame_skill:My_Queue
{

//* 初始化技能库 
	// ****************************************************************************
	// * Punch And Kick -- a simple 2D Fighting Game.
	// *
	// * Copyright (C) 2013 by
	// * Liu Chao
	// *
	// * This file is part of the Punch And Kick project, and may only be used,
	// * modified, and distributed under the terms of the GPLv2.
	// *
	// * (GPLv2 is abbreviation of GNU General Public License Version 2)
	// *
	// * By continuing to use, modify, or distribute this file you indicate that you
	// * have read the license and understand and accept it fully.
	// *
	// * The Punch And Kick project is distributed in the hope that it will be
	// * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
	// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPL v2 for
	// * more details.
	// *
	// * You should have received a copy of the GPLv2 along with this file. It is
	// * usually in the LICENSE.TXT file, If not, see <http://www.gnu.org/licenses/>.
	// * **************************************************************************

	// ****************************************************************************
	// * Punch And Kick -- 一个普通的2D格斗游戏
	// *
	// * 版权所有 (C) 2013 归属于
	// * 刘超
	// *
	// * 这个文件是 Punch And Kick 项目的一部分，并且只可以根据GPLv2许可协议来使用、
	// * 更改和发布。
	// *
	// * (GPLv2 是 GNU通用公共许可证第二版 的英文缩写)
	// *
	// * 继续使用、修改或发布本文件，表明您已经阅读并完全理解和接受这个许可协议。
	// *
	// * Punch And Kick 项目是基于技术交流目的而加以散布的，但不负任何担保责任，例
	// * 如：稳定性、可玩性、趣味性等的担保，甚至没有适销性或特定用途的隐含担保，详
	// * 情请参照GPLv2许可协议。
	// *
	// * 您应已收到附随于本文件的GPLv2许可协议的副本，它通常在LICENSE.TXT文件中，如果
	// * 没有，请查看：<http://www.gnu.org/licenses/>.
	// * **************************************************************************

	// 游戏角色的技能管理模块

	//#define DEBUG
	// ****************************************************************************
	// * Punch And Kick -- a simple 2D Fighting Game.
	// *
	// * Copyright (C) 2013 by
	// * Liu Chao
	// *
	// * This file is part of the Punch And Kick project, and may only be used,
	// * modified, and distributed under the terms of the GPLv2.
	// *
	// * (GPLv2 is abbreviation of GNU General Public License Version 2)
	// *
	// * By continuing to use, modify, or distribute this file you indicate that you
	// * have read the license and understand and accept it fully.
	// *
	// * The Punch And Kick project is distributed in the hope that it will be
	// * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
	// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPL v2 for
	// * more details.
	// *
	// * You should have received a copy of the GPLv2 along with this file. It is
	// * usually in the LICENSE.TXT file, If not, see <http://www.gnu.org/licenses/>.
	// * **************************************************************************

	// ****************************************************************************
	// * Punch And Kick -- 一个普通的2D格斗游戏
	// *
	// * 版权所有 (C) 2013 归属于
	// * 刘超
	// *
	// * 这个文件是 Punch And Kick 项目的一部分，并且只可以根据GPLv2许可协议来使用、
	// * 更改和发布。
	// *
	// * (GPLv2 是 GNU通用公共许可证第二版 的英文缩写)
	// *
	// * 继续使用、修改或发布本文件，表明您已经阅读并完全理解和接受这个许可协议。
	// *
	// * Punch And Kick 项目是基于技术交流目的而加以散布的，但不负任何担保责任，例
	// * 如：稳定性、可玩性、趣味性等的担保，甚至没有适销性或特定用途的隐含担保，详
	// * 情请参照GPLv2许可协议。
	// *
	// * 您应已收到附随于本文件的GPLv2许可协议的副本，它通常在LICENSE.TXT文件中，如果
	// * 没有，请查看：<http://www.gnu.org/licenses/>.
	// * **************************************************************************


	//* 初始化技能库 
	public static void SkillLibrary_Init()
	{
		Queue_Init(skill_library, typeof(SkillData_), null);
		skill_library_init = DefineConstantsGame_skill.TRUE;
		GlobalMembersSkills_common.CommonSkill_Register();
		GlobalMembersSkills_fighter.FighterSkill_Register();
		//MartialArtistSkill_Register();
		//KungFuSkill_Register();
		//JudoMasterSkill_Register();
		//TigerSkill_Register();
	}

//* 向技能库中添加新技能信息 
public delegate LCUI_BOOL can_useDelegate(GamePlayer_ UnnamedParameter1);
public delegate void run_skillDelegate(GamePlayer_ UnnamedParameter1);

	public static int SkillLibrary_AddSkill(string skill_name, SkillPriority_AAttack priority, SkillData_.can_useDelegate can_use, SkillData_.run_skillDelegate run_skill)
    {
	  return	SkillLibrary_AddSkill(skill_name,(int) priority, can_use, run_skill);
	}

	public static int SkillLibrary_AddSkill(string skill_name, SkillPriority_BAttack priority, SkillData_.can_useDelegate can_use, SkillData_.run_skillDelegate run_skill)
	{
		return SkillLibrary_AddSkill(skill_name, (int)priority, can_use, run_skill);
	}

	//* 向技能库中添加新技能信息 
	public static int SkillLibrary_AddSkill(string skill_name, int priority, SkillData_.can_useDelegate can_use, SkillData_.run_skillDelegate run_skill)
	{
		int i;
		int n;
		SkillData_ skill = new SkillData_();
		SkillData_ p_skill;

		if (skill_library_init == null)
		{
			return -1;
		}
		skill.skill_id = (int)BKDRHash(skill_name);
		n = Queue_GetTotal(skill_library);
		DEBUG_MSG("add skill: %s, id: %d, priority: %d\n", skill_name, skill.skill_id, priority);
	#if DEBUG
		DEBUG_MSG("skill list: \n");
		for(i =0; i<n; ++i)
		{
			p_skill = (SkillData_)Queue_Get(skill_library, i);
			if (p_skill == null)
			{
				continue;
			}
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro:
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro:
			//printf(__FILE__" %d: %s(): ""skill: %s, id: %d, priority: %d, pos: %d\n", __LINE__, System.Reflection.MethodBase.GetCurrentMethod().Name,p_skill.skill_name, p_skill.skill_id, p_skill.priority, i);
		}
		DEBUG_MSG("end skill list\n\n");
	#endif
		for(i =0; i<n; ++i)
		{
			p_skill = (SkillData_)Queue_Get(skill_library, i);
			if (p_skill == null)
			{
				continue;
			}
			DEBUG_MSG("skill: %s, id: %d, priority: %d, pos: %d\n", p_skill.skill_name, p_skill.skill_id, p_skill.priority, i);
			if(p_skill.skill_id == skill.skill_id)
			{
				p_skill.can_use = can_use;
				p_skill.run_skill = run_skill;
				return skill.skill_id;
			}
			if(p_skill.priority >= priority)
			{
				break;
			}
		}
		skill.priority = priority;
		skill.run_skill = run_skill;
		skill.can_use = can_use;
		//skill.skill_name = skill_name.Substring(0, 64);
		//skill.skill_name = skill.skill_name.Substring(0, 63);
		skill.skill_name = skill_name;
		DEBUG_MSG("i =%d\n", i);
		if(i >= n)
		{
			Queue_Add(skill_library, skill);
		}
		else
		{
			Queue_Insert(skill_library, i, skill);
		}
		return skill.skill_id;
	}



    //* 检测玩家是否拥有指定技能 

    //* 检测玩家是否拥有指定技能 
    public static LCUI_BOOL GamePlayer_HaveSkill(GamePlayer_ player, string skill_name)
	{
		int skill_id;
		skill_id = (int)BKDRHash(skill_name);
		return _GamePlayer_HaveSkill(player, skill_id);
	}

//* 初始化游戏角色拥有的技能的记录 

	//* 初始化游戏角色拥有的技能的记录 
	public static void GamePlayer_InitSkillRecord(GamePlayer_ player)
	{
		Queue_Init(player.skills, typeof(SkillRecord_), DstroySkillRecord);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_A_FINALBLOW);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_B_FINALBLOW);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_DEFENSE);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_A_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_B_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_JUMP);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_JUMP_A_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_JUMP_B_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_SPRINT_A_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_SPRINT_B_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_SPRINT_JUMP_A_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_SPRINT_JUMP_B_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_A_LIFT);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_B_LIFT);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_A_THROW);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_B_THROW);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_JUMP_ELBOW);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_JUMP_TREAD);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_RIDE);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_RIDE_A_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_RIDE_B_ATTACK);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_CATCH);
		GamePlayer_EnableSkill(player, DefineConstantsGame_skill.SKILLNAME_PUSH);
	}

//* 为游戏角色启用一个技能 

	//* 为游戏角色启用一个技能 
	public static int GamePlayer_EnableSkill(GamePlayer_ player, string skill_name)
	{
		SkillRecord_ rec = new SkillRecord_();
		rec.skill_id = (int)BKDRHash(skill_name);
		if (_GamePlayer_HaveSkill(player, rec.skill_id))
		{
			return -1;
		}
		rec.data = IntPtr.Zero;
		Queue_Add(player.skills, rec);
		return 0;
	}

//* 为游戏角色禁用一个技能 

	//* 为游戏角色禁用一个技能 
	public static int GamePlayer_DisableSkill(GamePlayer_ player, string skill_name)
	{
		int n;
		int exist_skill_id;
		int skill_id;

		skill_id = BKDRHash(skill_name);
		n = Queue_GetTotal(player.skills);
		while(n-->0)
		{
			exist_skill_id = ((SkillRecord_)Queue_Get(player.skills, n)).skill_id;
			// 如果该技能已经被启用，则移除该技能的记录
			if(exist_skill_id != 0 && exist_skill_id == skill_id)
			{
				Queue_Delete(player.skills, n);
				return 0;
			}
		}
		return -1;
	}

//* 从技能库中获取一个满足发动条件的技能 

	//* 从技能库中获取一个满足发动条件的技能 
	public static int SkillLibrary_GetSkill(GamePlayer_ player)
	{
		int i;
		int n;
		SkillData_ p_skill;

		n = Queue_GetTotal(skill_library);
		for(i =0; i<n; ++i)
		{
			p_skill = (SkillData_)Queue_Get(skill_library, i);
			if (p_skill == null)
			{
				continue;
			}
			DEBUG_MSG("skill: %s, id: %d, pos: %d\n", p_skill.skill_name, p_skill.skill_id, i);
			if (_GamePlayer_HaveSkill(player, p_skill.skill_id) == null)
			{
				DEBUG_MSG("player id: %d, not enable\n", player.id);
				continue;
			}
			if(p_skill.can_use==null)
			{
				DEBUG_MSG("no check\n");
				continue;
			}
			DEBUG_MSG("function addr: %p\n", p_skill.can_use);
			if(p_skill.can_use(player))
			{
				DEBUG_MSG("use this skill\n");
				return p_skill.skill_id;
			}
		}
		DEBUG_MSG("no skill\n");
		return -1;
	}

//* 让游戏角色发动技能 

	//* 让游戏角色发动技能 
	public static int GamePlayer_RunSkill(GamePlayer_ player, int skill_id)
	{
		int n;
		SkillData_ p_skill;

		n = Queue_GetTotal(skill_library);
		while(n-->0)
		{
			p_skill = (SkillData_)Queue_Get(skill_library, n);
			if (p_skill == null)
			{
				continue;
			}
			if(p_skill.skill_id == skill_id)
			{
				if(p_skill.run_skill!=null)
				{
					p_skill.run_skill(player);
				}
				return 0;
			}
		}
		return -1;
	}

	//#endif

	internal static LCUI_BOOL skill_library_init = DefineConstantsGame_skill.FALSE;
	internal static LCUI_Queue skill_library = new LCUI_Queue();

	internal static LCUI_BOOL _GamePlayer_HaveSkill(GamePlayer_ player, int skill_id)
	{
		int n;
		int exist_skill_id;

		n = Queue_GetTotal(player.skills);
		while(n-->0)
		{
			exist_skill_id = ((SkillRecord_)Queue_Get(player.skills, n)).skill_id;
			DEBUG_MSG("skill id: %d, pos: %d\n", exist_skill_id, n);
			if(exist_skill_id != 0 && exist_skill_id == skill_id)
			{
				return DefineConstantsGame_skill.TRUE;
			}
		}
		return DefineConstantsGame_skill.FALSE;
	}

	internal static void DstroySkillRecord(IntPtr arg)
	{
		SkillRecord_ p_data;
		p_data = (SkillRecord_)Marshal.PtrToStructure(arg,typeof(SkillRecord_));
		//p_data = (SkillRecord_)arg;
//		if(p_data.data)
//		{
////C++ TO C# CONVERTER TODO TASK: The memory management function 'free' has no equivalent in C#:
//			free(p_data.data);
//			p_data.data = null;
//		}
	}

	//* 获取已启用的技能 
	internal static SkillRecord_ GamePlayer_GetEnabledSkill(GamePlayer_ player, string skill_name)
	{
		int n;
		int skill_id;
		SkillRecord_ p_rec;

		skill_id = (int)BKDRHash(skill_name);
		n = Queue_GetTotal(player.skills);
		while(n-->0)
		{
			p_rec = (SkillRecord_)Queue_Get(player.skills, n);
			if(p_rec != null && p_rec.skill_id == skill_id)
			{
				return p_rec;
			}
		}
		return null;
	}

	//* 设置技能的数据，一些技能需要记录相应数据以在特殊情况下满足发动条件 
	public static int GamePlayer_SetSkillData(GamePlayer_ player, string skill_name, IntPtr p_data, int data_size)
	{
		SkillRecord_ p_rec;
		p_rec = GamePlayer_GetEnabledSkill(player, skill_name);
		if (p_rec == null)
		{
			return -1;
		}
//		if(!p_rec.data)
//		{
////C++ TO C# CONVERTER TODO TASK: The memory management function 'malloc' has no equivalent in C#:
//			p_rec.data = malloc(data_size);
//			if(!p_rec.data)
//			{
//				return -2;
//			}
//		}
////C++ TO C# CONVERTER TODO TASK: The memory management function 'memcpy' has no equivalent in C#:
//		memcpy(p_rec.data, p_data, data_size);
		return 0;
	}

	//* 获取技能的数据 
	public static IntPtr GamePlayer_GetSkillData(GamePlayer_ player, string skill_name)
	{
		SkillRecord_ p_rec;
		p_rec = GamePlayer_GetEnabledSkill(player, skill_name);
		if (p_rec == null)
		{
			return IntPtr.Zero;
		}
		return p_rec.data;
	}
}


public class SkillData_
{
	public int skill_id; //*< 技能ID 
	public string skill_name = new string(new char[64]); //*< 技能名称 
	public int priority; //*< 优先级 
	public delegate LCUI_BOOL can_useDelegate(GamePlayer_ UnnamedParameter1); //*< 回调函数，用于检测是否满足技能发动条件 
	public can_useDelegate can_use;
	public delegate void run_skillDelegate(GamePlayer_ UnnamedParameter1); //*< 回调函数，用于实现技能 
	public run_skillDelegate run_skill;
}

public class SkillRecord_
{
	public int skill_id;
	public IntPtr data;
}
